#! /bin/bash

ROOT_DIR=${PWD}
para=$*     #参数列表
num=$#      #获取参数个数
BOARD=$BOARD
UBOOT_DEFCONFIG=
KERNEL_DEFCONFIG=
BUILDROOT_DEFCONFIG=
ARCH=
PARAS=
UBOOT_FILE=
DTS_FILE=
CHIP=
SOC=
KERNEL_PATH=
UBOOT_PATH=
ROOTFS=debian
GUI=QT
JOBS=8
COMPILE_TOOLS=$ROOT_DIR/toolchains/gcc_aarch64_11/bin/aarch64-none-linux-gnu-

# 定义颜色
RED='\033[31m'
GREEN='\033[32m'
BLUE='\033[36m'
YELLOW='\033[33m'
NC='\033[0m' # No Color

function app()
{
	if [ x"$1" == x"clean" ]; then
		echo -e "\n${BLUE}######clean app######${NC}\n"
		if [ x"${GUI}" == x"QT" ]; then
			cd $ROOT_DIR/application/qt
			./mk.sh clean
			cd $ROOT_DIR
		else  # lvgl
			make clean -C application/lvgl
		fi
		return
	fi

	echo -e "\n${BLUE}######build app######${NC}\n"
	if [ x"${GUI}" == x"QT" ]; then
		cd $ROOT_DIR/application/qt
		./mk.sh
		cd $ROOT_DIR
	else  # lvgl
		make adaptoGUI_defconfig -C application/lvgl
		make -j$JOBS -C application/lvgl
	fi
}

function uboot()
{
	echo -e "\n${BLUE}######build uboot######${NC}\n"
	if ! which dtc >/dev/null 2>&1 ; then
		echo "没有dtc这个工具, 请用 ' sudo apt-get install device-tree-compiler '来安装"
		exit 1
	fi

	# RK 的 UBOOT 有自己的一套编译规则并且把他做成了脚本。不采用标准社区的编译方法。
	case $BOARD in
		lbcq1 | tspi)  # RK uboot
			cd $UBOOT_PATH
			./make.sh CROSS_COMPILE=${COMPILE_TOOLS} $SOC
		;;
		*)  # 社区标准 uboot
			make ARCH=arm CROSS_COMPILE=${COMPILE_TOOLS} $UBOOT_DEFCONFIG -C $UBOOT_PATH
			make ARCH=arm CROSS_COMPILE=${COMPILE_TOOLS} $UBOOT_PARAS -C $UBOOT_PATH -j$JOBS
		;;
	esac
}

function kernel()
{
	echo -e "\n${BLUE}######build kernel######${NC}\n"

	make $PARAS $KERNEL_DEFCONFIG -C $KERNEL_PATH
	make $PARAS -C $KERNEL_PATH -j$JOBS
}

function drivers()
{
	echo -e "\n${BLUE}######build drivers######${NC}\n"

	if [ ! -f "$KERNEL_PATH/vmlinux" ]; then
		kernel # 如果kernel没有编译应该先编译kernel
	fi

	make $PARAS KERNEL_SRC=$KERNEL_PATH -C $ROOT_DIR/drivers -j$JOBS $BOARD
}

function clean()
{
	app clean
	make clean -C $UBOOT_PATH
	make clean -C $KERNEL_PATH
	make clean -C drivers
}

function help()
{
	echo -e "${BLUE} ./mk all      --- build u-boot & linux & driver${NC}"
	echo -e "${BLUE} ./mk uboot    --- build u-boot only${NC}"
	echo -e "${BLUE} ./mk kernel   --- build kernel only${NC}"
	echo -e "${BLUE} ./mk clean    --- clean u-boot & linux${NC}"
	echo -e "${BLUE} ./mk app      --- build app${NC}"
	#echo -e "${RED} 注意：文件系统默认 debian 可以传参改变文件系统，但参数要放在 img 参数之前${NC}"
}

function cp_file_to_board_fs()
{
	# 打包大包之前必须保证已有文件系统。否则系统无法启动
	if [ ! -d $ROOT_DIR/output/$ROOTFS-$ARCH ]; then
		if [ -f $ROOT_DIR/output/$ROOTFS-$ARCH.tar.bz2 ]; then
			echo -e "${BLUE}taring rootfs ${NC}"
			tar -xjf $ROOT_DIR/output/$ROOTFS-$ARCH.tar.bz2 -C $ROOT_DIR/output
		else
			if [ "${ROOTFS}" = "debian" ]; then
				echo -e "${BLUE}building rootfs${NC}"
				cd $ROOT_DIR/output
				$ROOT_DIR/vendor/scripts/rootfs.sh $ARCH
				tar -jcf debian-$ARCH.tar.bz2 debian-$ARCH
				cd $ROOT_DIR
			else # buildroot
				echo "todo: build buildroot fs"
			fi
		fi
	fi
	# CP 基础的文件系统
	cp -r $ROOT_DIR/output/$ROOTFS-$ARCH/* $ROOT_DIR/output/$BOARD/fs
	cp -rfp $ROOT_DIR/vendor/ycfs/* $ROOT_DIR/output/$BOARD/fs

	touch $ROOT_DIR/output/$BOARD/fs/etc/yc-configs/yc-sys.conf
	echo "CHIP=$CHIP" >> $ROOT_DIR/output/$BOARD/fs/etc/yc-configs/yc-sys.conf
	echo "BOARD=$BOARD" >> $ROOT_DIR/output/$BOARD/fs/etc/yc-configs/yc-sys.conf

	# CP 编译的驱动
	mkdir -p $ROOT_DIR/output/$BOARD/fs/lib/modules
	cp `find $ROOT_DIR/drivers -name "*.ko"` $ROOT_DIR/output/$BOARD/fs/lib/modules

	# CP qt deb包
	cp $ROOT_DIR/output/qt/yckj-qt.deb $ROOT_DIR/output/$BOARD/fs/opt

	# CP 预编译的可执行文件
	cp $ROOT_DIR/vendor/tools/bin/$ARCH/* $ROOT_DIR/output/$BOARD/fs/usr/bin

	# CP 编译的应用程序
	mkdir -p $ROOT_DIR/output/$BOARD/fs/opt/yc-app
	if [ x"${GUI}" == x"QT" ]; then
		cp $ROOT_DIR/application/qt/build/adaptoGUI $ROOT_DIR/output/$BOARD/fs/opt/yc-app
		cp -rfp $ROOT_DIR/application/qt/thirdpart/libqui/lib/* $ROOT_DIR/output/$BOARD/fs/usr/lib/
		cp -rfp $ROOT_DIR/application/qt/thirdpart/libskin/lib/* $ROOT_DIR/output/$BOARD/fs/usr/lib/
	else
		cp $ROOT_DIR/application/lvgl/adaptoGUI $ROOT_DIR/output/$BOARD/fs/opt/yc-app
	fi
}

function AW_img()
{
	# 打包成一个完整的镜像
	echo -e "\n${BLUE}######build AW img######${NC}\n"

	dd if=/dev/zero of=$ROOT_DIR/output/$BOARD/yc-$BOARD.img bs=1M count=1024

	mkdir -p $ROOT_DIR/output/$BOARD/fs/
	cp $ROOT_DIR/$UBOOT_PATH/$UBOOT_FILE $ROOT_DIR/output/$BOARD
	cp $KERNEL_PATH/arch/$ARCH/boot/Image $ROOT_DIR/output/$BOARD
	cp $KERNEL_PATH/$DTS_FILE $ROOT_DIR/output/$BOARD

	cp_file_to_board_fs

	cp $ROOT_DIR/vendor/board/$BOARD/img.sh $ROOT_DIR/output/$BOARD
	cp $ROOT_DIR/vendor/board/$BOARD/boot.* $ROOT_DIR/output/$BOARD
	cd $ROOT_DIR/output/$BOARD
	sudo ./img.sh $ROOT_DIR/output/$BOARD/yc-$BOARD.img
	cd $ROOT_DIR
}

function RK_img()
{
	echo -e "\n${BLUE}######build RK img######${NC}\n"

	mkdir -p $ROOT_DIR/output/$BOARD/extboot/extlinux
	mkdir -p $ROOT_DIR/output/$BOARD/Image
	mkdir -p $ROOT_DIR/output/$BOARD/fs/
	cp $ROOT_DIR/vendor/board/$BOARD/* $ROOT_DIR/output/$BOARD/
	cp $ROOT_DIR/vendor/tools/rk_pack_tools/* $ROOT_DIR/output/$BOARD/

	cp_file_to_board_fs

	cd $ROOT_DIR/output/$BOARD/
	mv extlinux.conf extboot/extlinux
	mv boot.* extboot
	cp $KERNEL_PATH/arch/arm64/boot/Image extboot
	cp $KERNEL_PATH/$DTS_FILE extboot/rk-kernel.dtb

	# 打包kernel.img
	truncate -s 128M kernel.img
	fakeroot mkfs.ext2 -F -L "boot" -d extboot kernel.img

	# 打包 rootfs.img

	local EXTRA_SIZE_MB=100
	local IMAGE_SIZE_MB=$(( $(du -sh -m $ROOT_DIR/output/$BOARD/fs | cut -f1) + ${EXTRA_SIZE_MB} ))
	mkfs.ext4 -d $ROOT_DIR/output/$BOARD/fs rootfs.img ${IMAGE_SIZE_MB}M

	# 打包整体大包
	cp $UBOOT_PATH/uboot.img Image
	mv *.img Image
	mv MiniLoaderAll.bin Image
	mv parameter.txt Image

	./pack.sh $SOC yc-$BOARD.img
	cd $ROOT_DIR
}

function img()
{
	if [ "${CHIP}" == "RK" ]; then
		RK_img
	else
		AW_img
	fi
}

function get_board()
{
	if [ -f $ROOT_DIR/output/yc-board ]; then
		BOARD=`cat $ROOT_DIR/output/yc-board`
		case $BOARD in
			tspi)
			;;
			opi3l)
			;;
			lbcq1)
			;;
			*)
				rm -rf $ROOT_DIR/output/yc-board
			;;
		esac
	else
		echo -e "${BLUE}请选择板子型号 ${NC}\n"
		echo -e "${BLUE} 0 - tspi ${NC}"
		echo -e "${BLUE} 1 - opi3l ${NC}"
		echo -e "${BLUE} 2 - lbcq1 ${NC}"

		read board
		case $board in
		"0" )
			BOARD=tspi
		;;
		"1")
			BOARD=opi3l
		;;
		"2")
			BOARD=lbcq1
		;;
		esac
		mkdir -p $ROOT_DIR/output
		touch $ROOT_DIR/output/yc-board
		echo $BOARD > $ROOT_DIR/output/yc-board
	fi
}

function qt()
{
	if [ -f $ROOT_DIR/output/qt/yckj-qt.deb ]; then
		echo -e "\n${BLUE}QT already build${NC}\n"
		return
	fi
	echo -e "\n${BLUE}build qt env${NC}\n"
	mkdir -p $ROOT_DIR/toolchains/qt/DEBIAN
	mkdir -p $ROOT_DIR/output/qt
	cd $ROOT_DIR/output/qt
	$ROOT_DIR/vendor/scripts/tslib.sh $ROOT_DIR/toolchains/qt
	$ROOT_DIR/vendor/scripts/alsa.sh $ROOT_DIR/toolchains/qt
	$ROOT_DIR/vendor/scripts/qt.sh $ROOT_DIR/toolchains/qt

	mv $ROOT_DIR/toolchains/qt/examples $ROOT_DIR/output/qt

	# 编译结束开始打包
	touch $ROOT_DIR/toolchains/qt/DEBIAN/control
	CONTROL=$ROOT_DIR/toolchains/qt/DEBIAN/control

	echo "Package: YCKJ-QT" > $CONTROL
	echo "Version: 1.0" >> $CONTROL
	echo "Section: base" >> $CONTROL
	echo "Priority: optional" >> $CONTROL
	echo "Architecture: all" >> $CONTROL
	echo "Depends:" >> $CONTROL
	echo "Maintainer: ChenBlue" >> $CONTROL
	echo "Description: yckj qt env deb" >> $CONTROL

	cd $ROOT_DIR/toolchains
	dpkg -b qt yckj-qt.deb
	mv $ROOT_DIR/toolchains/yckj-qt.deb $ROOT_DIR/output/qt
	rm -rf $ROOT_DIR/toolchains/qt/DEBIAN
	cd $ROOT_DIR
}

if [ $num -lt 1 ]; then  # if (num < 1)
	help
	exit 1
fi

# 检查第一个参数是不是板子型号
# clean 和 app 不依赖板子型号。也可以过


function config_env()
{
	case "$BOARD" in
		lbcq1 )
			mkdir -p $ROOT_DIR/output/$BOARD
			UBOOT_PATH=$ROOT_DIR/bootloader/rk-2017
			SOC=rk3528

			KERNEL_PATH=$ROOT_DIR/kernel/rk-5.10
			KERNEL_DEFCONFIG=lubancat_linux_rk3528_defconfig
			DTS_FILE=arch/arm64/boot/dts/rockchip/rk3528-lubancat-q1.dtb
			PARAS="ARCH=arm64 CROSS_COMPILE=${COMPILE_TOOLS}"
			ARCH=arm64
			CHIP=RK
		;;
		tspi )
			mkdir -p $ROOT_DIR/output/$BOARD
			UBOOT_PATH=$ROOT_DIR/bootloader/rk-2017
			SOC=rk3568

			KERNEL_PATH=$ROOT_DIR/kernel/rk-5.10
			KERNEL_DEFCONFIG=tspi_defconfig
			DTS_FILE=arch/arm64/boot/dts/rockchip/rk3566-tspi.dtb
			PARAS="ARCH=arm64 CROSS_COMPILE=${COMPILE_TOOLS}"
			ARCH=arm64
			CHIP=RK
			;;
		nano | nano_tf)
			mkdir -p $ROOT_DIR/output/$BOARD
			if [ "$1" = "nano" ]; then
				UBOOT_DEFCONFIG=f1c100s_defconfig
			else
				UBOOT_DEFCONFIG=f1c100s_tf_defconfig
			fi
			KERNEL_DEFCONFIG=f1c100s_defconfig
			BUILDROOT_DEFCONFIG=f1c100s_defconfig
			PARAS="ARCH=arm CROSS_COMPILE=arm-linux-"
			;;
		opi3l )
			mkdir -p $ROOT_DIR/output/$BOARD
			UBOOT_PATH=$ROOT_DIR/bootloader/u-boot
			UBOOT_DEFCONFIG=orangepi_3_defconfig

			KERNEL_PATH=$ROOT_DIR/kernel/linux
			KERNEL_DEFCONFIG=defconfig
			PARAS="ARCH=arm64 CROSS_COMPILE=${COMPILE_TOOLS}"
			DTS_FILE=arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3-lts.dtb
			ARCH=arm64
			UBOOT_FILE=u-boot-sunxi-with-spl.bin
			CHIP=AW
			;;
		opi3b )
			mkdir -p $ROOT_DIR/output/$BOARD
			UBOOT_DEFCONFIG=orangepi-3b-rk3566_defconfig
			KERNEL_DEFCONFIG=orangepi3b_defconfig
			PARAS="ARCH=arm64 CROSS_COMPILE=${COMPILE_TOOLS}"
			;;
		*)
			get_board
			config_env
			;;
	esac
}

config_env

# 检查工具链是否存在。如果不存在则从网络上下载、解压并设置
if [ ! -d "$ROOT_DIR/toolchains/gcc_aarch64_11" ]; then
	# 工具链不存在 需要下载工具链
	mkdir -p toolchains
	cd toolchains
	wget https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
	tar -xf gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
	mv gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu gcc_aarch64_11  #重命名个简短点的名字
	rm -rf gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz  # 删除工具链的压缩包 减少电脑硬盘负担
	cd -
fi
export PATH=$PATH:$ROOT_DIR/toolchains/gcc_aarch64_11/bin # 将工具链添加到环境变量   仅本shell生效

# wget https://www.nucleisys.com/upload/files/toochain/gcc/nuclei_riscv_newlibc_prebuilt_linux64_2022.12.tar.bz2


for i in $*
do
	case "$i" in
		all)
			uboot
			kernel
			drivers
			qt
			app
			img
		;;
		uboot | u-boot )
			uboot
		;;
		linux | kernel )
			kernel
		;;
		drivers | driver)
			drivers
		;;
		buildroot | debian)
			ROOTFS=$i
		;;
		img)
			img
		;;
		clean)
			clean
			exit 0
			;;
		app)
			app
			exit 0
			;;
		qt)
			qt
			exit 0
			;;
		help)
			help
			exit 0
			;;
		*)
		;;
	esac
done

echo -e "\n${YELLOW}board=$BOARD"

